package com.xneure.code.commport;

import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;
import jssc.SerialPortList;

/**
 * <p>
 * 串口操作对象
 * </p>
 * <p>
 * Copyright: 版权所有<br>
 *
 * @author zhangjun
 * @version 2018年9月29日
 */
public class CommPort{
	private SerialPort serialPort;
	private PortListener portListener;
	private ByteArrayOutputStream baos = new ByteArrayOutputStream(1024 * 10);
	private String encoding = Charset.defaultCharset().name();

	public static String[] getCommPorts(){
		return SerialPortList.getPortNames();
	}

	public CommPort(String port){
		setPort(port);
	}

	public String getEncoding(){
		return encoding;
	}

	public void setEncoding(String encoding){
		this.encoding = encoding;
	}

	public void setPort(String port){
		this.serialPort = new SerialPort(port);
	}

	public boolean send(String data){
		try{
			serialPort.writeString(data);
			return true;
		}catch(SerialPortException e){
			e.printStackTrace();
			return false;
		}
	}
	private CommPort getThis() {
		return this;
	}
	public void addListener(PortListener pl){
		this.portListener = pl;
	}

	public boolean send(byte... data){
		try{
			serialPort.writeBytes(data);
			return true;
		}catch(SerialPortException e){
			e.printStackTrace();
			return false;
		}
	}

	public boolean send(byte data){
		try{
			serialPort.writeByte(data);
			return true;
		}catch(SerialPortException e){
			e.printStackTrace();
			return false;
		}
	}

	public boolean sendString(String data){
		try{
			serialPort.writeString(data);
			return true;
		}catch(SerialPortException e){
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 设置串口参数
	 * 
	 * @param baudrate 波特率
	 * @param dataBits 数据位
	 * @param stopBits 停止位
	 * @param parity 校验
	 */
	public void setParams(int baudrate,int dataBits,int stopBits,int parity){
		try{
			serialPort.setParams(baudrate,dataBits,stopBits,parity);
		}catch(SerialPortException e){
			e.printStackTrace();
		}
	}

	public boolean open(){
		try{
			if(serialPort.isOpened() == false){
				boolean openPort = serialPort.openPort();
				if(openPort){
					serialPort.addEventListener(new SerialPortEventListener(){
						@Override
						public void serialEvent(SerialPortEvent serialPortEvent){
							try{
								byte[] readBytes = serialPort.readBytes();
								if(null == readBytes){
									return;
								}
								baos.write(readBytes);
								if(null != portListener){
									PortEvent peEvent = new PortEvent(getThis(),serialPortEvent,baos.toByteArray());
									portListener.event(peEvent);
								}
							}catch(Exception e){
								e.printStackTrace();
							}
						}
					});
				}
				return openPort;
			}else{
				return false;
			}
		}catch(SerialPortException e){
			return false;
		}
	}

	/**
	 * 清空接收到的数据
	 */
	public void emptyRead(){
		baos.reset();
	}

	public byte[] readData(){
		try{
			return baos.toByteArray();
		}finally{
			emptyRead();
		}
	}

	public String readString(){
		return new String(readData(),Charset.forName(this.encoding));
	}

	public boolean close(){
		try{
			if(serialPort.isOpened()){
				return serialPort.closePort();
			}else{
				return false;
			}
		}catch(SerialPortException e){
			return false;
		}
	}
}
